import classnames from "classnames";
import Skeleton from 'taro-skeleton'
import React, { Component } from 'react';
import Taro from '@tarojs/taro';
import {View, Image, Text, ScrollView, Block} from '@tarojs/components';
import {AtIcon} from 'taro-ui';
import {GetRequest} from "../../utils/tools";
import {http} from "../../utils/http";
import {TARO_ENV, APP_SCENIC_CARD} from "../../constants/api";
import MenuNavs from "./components/Menus";
import AudioPlay from "./components/Audio";
import "./index.scss";

type PageState = {
  scrollLeft: any
  scenicDetail: any
  scenicImageWidth: any
  scenicList: any
  showLoading: any
  scenicListOri: any
  currentPlayAudio: any
}

export default class ScenicCard extends Component {
  state: PageState = {
    showLoading: true,
    scrollLeft: 0,
    scenicImageWidth: 0,
    scenicDetail: {},
    scenicList: [],
    scenicListOri: [],
    currentPlayAudio: null, // 当前播放对象
  }

  async UNSAFE_componentWillMount() {
    await this.getDetail();
  }

  componentWillUnmount() {
    this.setState({currentPlayAudio: null});
    clearInterval(this.timer)
  }

  timer: any = ''
  flag: any = true

  // deep clone
  deepClone(source) {
    const targetObj = source.constructor === Array ? [] : {};
    Object.keys(source).forEach(keys => {
      if (source[keys] && typeof source[keys] === 'object') {
        targetObj[keys] = this.deepClone(source[keys]);
      } else {
        targetObj[keys] = source[keys];
      }
    })
    return targetObj;
  }

  // get detail
  getDetail = async () => {
    const reqParam = Taro.getCurrentInstance().router.params;
    const {uuid} = reqParam;
    Taro.showLoading({title: "加载中", mask: true});
    const res = await http.HPost(APP_SCENIC_CARD, {uuid});
    const {spots, scenic} = res.data;
    const scenicList = spots.map(item => ({
      ...item,
      photo_urls: item.photo_url.split(","),
      autoplay: false,
      audioPlayStatus: "pause",
      audioPlayIcon: "play",
      audioPlayTime: "",
      audioAction: {
        method: 'pause'
      }
    }));
    const scenicListOri = spots.map(item => ({
      ...item,
      photo_urls: item.photo_url.split(","),
      autoplay: false,
      audioPlayStatus: "pause",
      audioPlayIcon: "play",
      audioPlayTime: "",
      audioAction: {
        method: 'pause'
      }
    }));
    const windowWidth = (Taro.getSystemInfoSync()).windowWidth
    const scenicImageWidth =  (await Taro.getImageInfo({src: scenic.scenic_photo})).width
    let isScroll = false
    if (scenicImageWidth > windowWidth * 2) {
      isScroll = true
    }
    this.setState({
      scenicImageWidth,
      scenicDetail: scenic,
      showLoading: false,
      scenicList,
      scenicListOri,
    }, async () => {
      Taro.hideLoading();
      if (isScroll) {
        this.handlerScrollLeft()
      }
    })
  };

  // view detail
  viewDetail = () => {
    const {uuid} = this.state.scenicDetail;
    Taro.navigateTo({
      url: `/common/scenic/detail?itemId=${uuid}`
    })
  };

  // play
  handlePlay_H5 = (e, id, idx) => {
    const {currentPlayAudio, scenicListOri} = this.state;
    const tempScenicList = this.deepClone(this.state.scenicListOri); // 避免直接使用原列表造成死循环
    // 没有播放
    if (!currentPlayAudio) {
      const tempPlayAudio = Object.assign({}, tempScenicList[idx]);
      tempScenicList[idx].autoplay = true;
      tempScenicList[idx].audioPlayIcon = "pause";
      this.setState({
        currentPlayAudio: tempPlayAudio,
        scenicList: tempScenicList
      });
    } else {
      // 非当前播放
      if (currentPlayAudio.id !== id) {
        const tempPlayAudio = Object.assign({}, scenicListOri[idx]); // 更新播放对象(assign: 避免播放过, 但不是当前播放时, 仍出现进度条)
        // 重置组件(用于重新渲染播放组件: 重置非当前组件的所有状态, 避免出现多个同时播放)
        for (let i = 0, len = tempScenicList.length; i < len; i++) {
          tempScenicList[i].audio_url = ""; // 重置组件的方式
          tempScenicList[idx].autoplay = false;
          tempScenicList[i].audioPlayIcon = "play";
          tempScenicList[i].audioPlayTime = "";
        }
        this.setState({
          currentPlayAudio: tempPlayAudio,
          scenicList: tempScenicList
        });

        setTimeout(() => {
          // 重新渲染组件
          for (let i = 0, len = tempScenicList.length; i < len; i++) {
            tempScenicList[i].audio_url = scenicListOri[i].audio_url;
            // 重新渲染播放组件
            if (tempScenicList[i].id === tempPlayAudio.id) {
              tempScenicList[i].audio_url = tempPlayAudio.audio_url;
              tempScenicList[idx].autoplay = true;
              tempScenicList[i].audioPlayIcon = "pause";
            }
          }

          this.setState({scenicList: tempScenicList});
        }, 1)
      } else {
        // 更新当前的播放状态图标
        for (let i = 0, len = tempScenicList.length; i < len; i++) {
          if (tempScenicList[i].id === currentPlayAudio.id) {
            tempScenicList[idx].autoplay = true; // 对于播放结束时的场景
            tempScenicList[i].audioPlayIcon = "pause";
            tempScenicList[i].audioPlayTime = currentPlayAudio.audioPlayTime;
            break;
          }
        }
        this.setState({scenicList: tempScenicList});
      }
    }
  };
  // pause
  handlePause_H5 = (e, id, idx) => {
    const {scenicList, currentPlayAudio} = this.state;
    scenicList[idx].audioPlayIcon = "play";
    scenicList[idx].audioPlayTime = currentPlayAudio.audioPlayTime;
    this.setState({scenicList});
  };
  // ended
  handleEnded_H5 = (e, id, idx) => {
    const {scenicList} = this.state;
    scenicList[idx].autoplay = false;
    scenicList[idx].audioPlayIcon = "play";
    scenicList[idx].audioPlayTime = "";
    this.setState({scenicList});
  };
  // TimeUpdate
  handleTimeUpdate_H5 = (e, id, idx) => {
    const {scenicList, currentPlayAudio} = this.state;
    const {currentTime, duration} = e.detail;
    const audioPlayTime = Math.floor(currentTime / duration * 100);

    scenicList[idx].audioPlayTime = `${audioPlayTime}%`;
    currentPlayAudio.audioPlayTime = `${audioPlayTime}%`;
    this.setState({scenicList, currentPlayAudio});
  };

  // play
  handlePlay = (e, id, idx) => {
  };
  // pause
  handlePause = (e, id, idx) => {
  };
  // ended
  handleEnded = (e, id, idx) => {
    let {scenicList, currentPlayAudio} = this.state;
    scenicList[idx].autoplay = false;
    scenicList[idx].audioPlayIcon = "play";
    scenicList[idx].audioPlayStatus = "pause";
    scenicList[idx].audioPlayTime = "";
    scenicList[idx].audioAction = Object.assign({}, {
      method: "pause"
    });
    currentPlayAudio = Object.assign({}, scenicList[idx]);
    this.setState({scenicList, currentPlayAudio});
  };
  // TimeUpdate
  handleTimeUpdate = (e, id, idx) => {
    const {currentTime, duration} = e.detail;
    let {scenicList, currentPlayAudio} = this.state;

    const audioPlayTime = Math.floor(currentTime / duration * 100);
    scenicList[idx].audioPlayTime = `${audioPlayTime}%`;
    currentPlayAudio = Object.assign({}, scenicList[idx]);
    this.setState({scenicList, currentPlayAudio});
  };

  // click audio for wechat-miniapp
  handleClickAudio(item, idx) {
    if (TARO_ENV === "weapp") {
      const audioCtx = wx.createAudioContext(`audioPlay_${item.id}`);
      const {currentPlayAudio, scenicListOri} = this.state;
      const tempScenicList = this.deepClone(this.state.scenicListOri); // 避免直接使用原列表造成死循环
      let tempPlayAudio = null;

      if (currentPlayAudio) {
        tempPlayAudio = Object.assign({}, scenicListOri[idx]);
        // 非当前播放
        if (currentPlayAudio.id !== tempPlayAudio.id) {
          /**
           * 重置播放状态(与H5端有差异)
           * PS: 只能重置为暂停. 若要重置为"初始播放", 需要重置两次(setState):
           * first: {method: "pause"}, 播放状态为"暂停"
           * second: {method: "setCurrentTime", data: 0}, 当前播放时间为"0"
           **/
          for (let i = 0, len = tempScenicList.length; i < len; i++) {
            tempScenicList[i].audioPlayIcon = "play";
            tempScenicList[i].audioPlayStatus = "pause";
            tempScenicList[i].audioPlayTime = "";
            // 只能暂停
            tempScenicList[i].audioAction = Object.assign({}, {
              method: "pause"
            });
            // 重新渲染播放组件
            if (tempScenicList[i].id === item.id) {
              tempScenicList[i].audioPlayIcon = "pause";
              tempScenicList[i].audioPlayStatus = "play";
              tempScenicList[i].audioPlayTime = "";
              tempScenicList[i].audioAction = Object.assign({}, {
                method: "play"
              });
            }
          }
        } else {
          // 当前播放: 仅更新播放状态
          for (let i = 0, len = tempScenicList.length; i < len; i++) {
            if (tempScenicList[i].id === item.id) {
              tempScenicList[i].audioPlayTime = currentPlayAudio.audioPlayTime; // 避免进度条重新渲染
              if (item.audioPlayStatus === "play") {
                // console.log("暂停");
                tempScenicList[i].audioPlayIcon = "play";
                tempScenicList[i].audioPlayStatus = "pause";
                tempScenicList[i].audioAction = Object.assign({}, {
                  method: "pause"
                });
              } else {
                // console.log("播放");
                tempScenicList[i].audioPlayIcon = "pause";
                tempScenicList[i].audioPlayStatus = "play";
                tempScenicList[i].audioAction = Object.assign({}, {
                  method: "play"
                });
              }
              break;
            }
          }
        }
      } else {
        // 没有播放 || 非当前播放
        tempPlayAudio = Object.assign({}, tempScenicList[idx]);
        const tempAction = {method: "play"};
        if (item.audioPlayStatus === "play") {
          tempAction.method = "pause";
        } else {
          tempAction.method = "play";
        }
        // 重置播放状态及图标
        for (let i = 0, len = tempScenicList.length; i < len; i++) {
          // 重新渲染播放组件
          if (tempScenicList[i].id === item.id) {
            tempScenicList[i].audioPlayIcon = "pause";
            tempScenicList[i].audioPlayStatus = "play";
            tempScenicList[i].audioAction = Object.assign({}, tempAction);
          }
        }
      }
      this.setState({currentPlayAudio: tempPlayAudio, scenicList: tempScenicList});
    }
  }

  handlerOnScrollToUpper(e) {
    this.flag = true
    this.handlerScrollLeft()
  }

  handlerOnScrollToLower(e) {
    this.flag = false
    this.handlerScrollLeft()
  }

  handlerScrollLeft() {
    clearInterval(this.timer)
    this.timer = setInterval(async () => {
      let scrollLeft = this.state.scrollLeft
      scrollLeft += this.flag ? 1 : -1
      this.setState({scrollLeft})
    }, 16)
  }

  handleClickMenu = (menuItem) => {
    const { currentPlayAudio } = this.state;
    const tempScenicList = this.deepClone(this.state.scenicListOri);
    let tempPlayAudio = null;
    // 当前如果有播放: 暂停
    if(currentPlayAudio && currentPlayAudio.audioPlayStatus === "play") {
      for (let i = 0, len = tempScenicList.length; i < len; i++) {
        if (tempScenicList[i].id === currentPlayAudio.id) {
          tempPlayAudio = Object.assign({}, tempScenicList[i]);
          tempScenicList[i].audioPlayTime = currentPlayAudio.audioPlayTime;
          tempScenicList[i].audioPlayIcon = "play";
          tempScenicList[i].audioPlayStatus = "pause";
          tempScenicList[i].audioAction = Object.assign({}, {
            method: "pause"
          });
          break;
        }
      }
    }
    setTimeout(() => {
      this.setState({currentPlayAudio: tempPlayAudio, scenicList: tempScenicList});
    }, 0)
  };

  render() {
    const {
      scenicDetail,
      scrollLeft,
      showLoading,
      scenicImageWidth,
      scenicList,
      currentPlayAudio
    } = this.state;

    return (
      <View className='scenic-card-page'>
        <Skeleton title loading={showLoading} titleWidth='100%' rowHeight='150px'>
          <Block>
            {
              scenicDetail.scenic_photo &&
              <ScrollView enableFlex scrollX onScrollToUpper={this.handlerOnScrollToUpper.bind(this)}
                onScrollToLower={this.handlerOnScrollToLower.bind(this)} scrollLeft={scrollLeft}
                className='scenic-card-img-wrap'
                upperThreshold={10}
              >
                <Image
                  style={`min-width: 100vw;height: 100vh; width: ${scenicImageWidth}px`}
                  mode='heightFix'
                  src={scenicDetail.scenic_photo}
                />
              </ScrollView>
            }
          </Block>
        </Skeleton>
        <Skeleton title loading={showLoading} titleWidth='100%' rowHeight='150px'>
          <Block>
            <View className='scenic-card-info-wrap'>
              <View className='scenic-intro'>
                {
                  scenicDetail.is_free_visit === 1 && scenicDetail.rank &&
                  <View className='si-label'>
                    {
                      scenicDetail.is_free_visit &&
                      <Text className='sil-item clr1'>免费入园</Text>
                    }
                    {
                      scenicDetail.rank &&
                      <Text className='sil-item clr2'>{scenicDetail.rank}A</Text>
                    }
                  </View>
                }
                <View className='si-title'>{scenicDetail.name}</View>
                <View className='si-desc'>{scenicDetail.scenic_introduction}</View>
                <View className='si-link'>
                  <View className='sil-box'>
                    <Text className='link' onClick={this.viewDetail}>详情</Text>
                  </View>
                </View>
              </View>
              {TARO_ENV !== 'tt' && <View className='scenic-audio'>
                <View className='sa-title'>景点解说</View>
                <View className='sa-list'>
                  {
                    scenicList.map((item, index) => (
                      <View className='sal-item' key={index}>
                        <View className='sali-cover'>
                          {item.photo_urls && item.photo_urls[0] && <Image
                            src={item.photo_urls[0]}
                            className='cover-img'
                          />}
                          <AtIcon
                            value={item.audioPlayIcon}
                            size={item.audioPlayIcon === "play" ? "20" : "26"}
                            color={item.audioPlayIcon === "pause" ? "#0ce412" : "#fff"}
                            className={classnames("cover-icon", {
                              "cover-icon-weapp": TARO_ENV === "weapp"
                            })}
                            onClick={() => this.handleClickAudio(item, index)}
                          />
                          {
                            item.audioPlayTime &&
                            <View className='audio-progress'>
                              <View className='progress-bar' style={{width: item.audioPlayTime}} />
                            </View>
                          }
                          {
                            TARO_ENV === "h5" ?
                              (!currentPlayAudio || item.id === currentPlayAudio.id) ?
                                <AudioPlay
                                  autoplay={item.autoplay}
                                  audioUrl={item.audio_url}
                                  itemId={item.id}
                                  handlePlay={(e) => this.handlePlay_H5(e, item.id, index)}
                                  handlePause={(e) => this.handlePause_H5(e, item.id, index)}
                                  handleEnded={(e) => this.handleEnded_H5(e, item.id, index)}
                                  handleTimeUpdate={(e) => this.handleTimeUpdate_H5(e, item.id, index)}
                                />
                                :
                                <AudioPlay
                                  autoplay={item.autoplay}
                                  audioUrl={item.audio_url}
                                  itemId={item.id}
                                  handlePlay={(e) => this.handlePlay_H5(e, item.id, index)}
                                  handlePause={(e) => this.handlePause_H5(e, item.id, index)}
                                  handleEnded={(e) => this.handleEnded_H5(e, item.id, index)}
                                  handleTimeUpdate={(e) => this.handleTimeUpdate_H5(e, item.id, index)}
                                />
                              :
                              <AudioPlay
                                audioAction={item.audioAction}
                                autoplay={item.autoplay}
                                audioUrl={item.audio_url}
                                itemId={item.id}
                                handlePlay={(e) => this.handlePlay(e, item.id, index)}
                                handlePause={(e) => this.handlePause(e, item.id, index)}
                                handleEnded={(e) => this.handleEnded(e, item.id, index)}
                                handleTimeUpdate={(e) => this.handleTimeUpdate(e, item.id, index)}
                              />
                          }
                        </View>
                        <View className='sali-title'>{item.name}</View>
                      </View>
                    ))
                  }
                </View>
              </View>}
              <MenuNavs scenicDetail={scenicDetail} idx={0} handleClickMenu={this.handleClickMenu} />
            </View>
          </Block>
        </Skeleton>
      </View>
    )
  }
}
